﻿<template>
  <div>
    <p>计数器：{{ count }}</p>
    <button @click="increment">增加计数</button>
    <p>消息：{{ message }}</p>
    <input v-model="message" placeholder="输入消息">
    <p>双倍计数：{{ doubleCount }}</p>
    <p>组合消息：{{ combinedMessage }}</p>
    <button @click="stopWatchCountListener">停止计数监听</button>
    <button @click="triggerAsyncOperation">触发异步操作</button>
    <p>异步结果：{{ asyncResult }}</p>
  </div>
</template>

<script setup>
import {ref, reactive, computed, watch, watchEffect} from 'vue';

// 1. 创建 ref 和 reactive 对象
const count = ref(0); // 单个 ref 对象
const message = ref('你好，Vue!'); // 绑定到 v-model 的 ref 对象
const state = reactive({
  additionalMessage: '欢迎使用 Vue 组合式 API'
});
const asyncResult = ref(''); // 用于存储异步操作结果

// 2. 创建计算属性
const doubleCount = computed(() => count.value * 2);

// 3. 创建计算属性来组合消息
const combinedMessage = computed(() => `${message.value} - ${state.additionalMessage}`);

// 4. 创建一个方法来增加计数
const increment = () => {
  count.value++;
};

// 5. watch 的第一个参数可以是多种形式的数据源
const countWatcher = watch(
    count, // 数据源，可以是 ref、reactive、计算属性、getter 函数或它们组成的数组
    (newCount, oldCount) => {
      console.log(`计数从 ${oldCount} 变为 ${newCount}`);
    },
    {immediate: true} // 配置选项：立即执行回调
);

watch(
    message, // 使用 ref 对象作为数据源
    (newMessage, oldMessage) => {
      console.log(`消息从 "${oldMessage}" 变为 "${newMessage}"`);
    }
);

watch(
    doubleCount, // 使用计算属性作为数据源
    (newDoubleCount, oldDoubleCount) => {
      console.log(`双倍计数从 ${oldDoubleCount} 变为 ${newDoubleCount}`);
    }
);

watch(
    combinedMessage, // 使用计算属性作为数据源
    (newCombinedMessage, oldCombinedMessage) => {
      console.log(`组合消息从 "${oldCombinedMessage}" 变为 "${newCombinedMessage}"`);
    }
);

watch(
    [count, message], // 使用数组作为数据源
    ([newCount, newMessage], [oldCount, oldMessage]) => {
      console.log(`计数从 ${oldCount} 变为 ${newCount}`);
      console.log(`消息从 "${oldMessage}" 变为 "${newMessage}"`);
    }
);

// 6. watchEffect 示例：不需要指定数据源，会自动追踪
watchEffect(() => {
  console.log(`watchEffect - 计数：${count.value}`);
  console.log(`watchEffect - 消息：${message.value}`);
});

// 7. 其他 watch 配置选项
watch(
    message,
    (newMessage, oldMessage) => {
      console.log(`带有 deep 和 immediate 配置的 watch 回调：消息从 "${oldMessage}" 变为 "${newMessage}"`);
    },
    {
      deep: true, // 深度监听，适用于监听对象或数组
      immediate: false // 是否在侦听器创建时立即调用回调
    }
);

// 8. 停止监听器示例
const stopWatchCount = watch(
    count,
    (newCount, oldCount) => {
      console.log(`停止监听计数从 ${oldCount} 变为 ${newCount} (这个监听器可以停止)`);
    },
    {immediate: true}
);

const stopWatchCountListener = () => {
  stopWatchCount(); // 调用返回的函数来停止监听器
  console.log('计数监听器已停止');
};

// 9. 异步监听示例
const asyncWatcher = watch(
    message,
    async (newMessage, oldMessage) => {
      console.log(`异步消息监听器：消息从 "${oldMessage}" 变为 "${newMessage}"`);
      const result = await performAsyncOperation(newMessage);
      asyncResult.value = `异步操作完成后的新消息：${result}`;
      console.log(asyncResult.value);
    }
);

// 10. 模拟异步操作
const performAsyncOperation = async (newMessage) => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(newMessage);
    }, 2000);
  });
};

// 11. 手动触发异步操作
const triggerAsyncOperation = async () => {
  const result = await performAsyncOperation(message.value);
  asyncResult.value = `手动触发的异步操作完成后的新消息：${result}`;
  console.log(asyncResult.value);
};
</script>
